//
//  Board.h
//  Mockup
//
//  Created by JOHN HODGSON 3/2/10.
//  Copyright 2010 Mac-Easy@USC. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Tile.h"
#import "Utils.h"
#import "Matrix.h"

//Game board dimensions
#define ARRAYWIDTH 8
#define ARRAYHEIGHT 11

//Score board dimensions 
#define SCOREWIDTH 9
#define SCOREHEIGHT 2

@interface Board : NSObject {	
	//Score variable
	NSInteger score;
	
	//To help save the time from GameVC
	NSInteger time;
	
	//Class instance of difficulty level
	difficulty_t difficultyLevel;
	
	//Matricies
	NSInteger matrix[ARRAYWIDTH][ARRAYHEIGHT]; //matrix is the main back-end matrix representation of the tiles
	NSInteger matchMatrix[ARRAYWIDTH][ARRAYHEIGHT]; //matchMatrix holds 0s and 1s, with 1s representing matched tiles
	Tile  * tiles[ARRAYWIDTH + 2][ARRAYHEIGHT + 2]; //tiles is the front-end matrix representation of the tiles
	NSInteger scoreMatrix[SCOREWIDTH][SCOREHEIGHT]; //scoreMatrix keeps track of how many matches were made, and what type of matches they are

	boardstate_t state;
	
	direction_t currentDirection ;	
}

/** PROPERTIES **/
@property (nonatomic) boardstate_t state;
@property (nonatomic) NSInteger score;
@property (nonatomic) NSInteger time;

/** METHODS **/
//Matrix methods
-(id)initWithRandomMatrix:(int)difficulty; //Builds random matrix for the front end, taking into account selected difficulty
-(id)initWithContentOfFile:(NSString *) filename;

-(void) buildMatrix:(int)diffNum; //Builds random matrix for the back end, taking into account selected difficulty
-(void) buildZeroesMatrix; //Sets matchMatrix to zeroes
-(void) buildScoreMatrix; //Sets up a matrix that keeps track of the scores.
//<<<<<<< .mine
//-(void) findSpecificMatches; //Populates the scoreMatrix
//=======
-(void) findMatchSpecifics:(int[ARRAYWIDTH][ARRAYHEIGHT]) _matchMatrix; //Populates the scoreMatrix
//>>>>>>> .r101
-(BOOL) checkForMatches:(int[ARRAYWIDTH][ARRAYHEIGHT])checkMatrix; //Determines if there are matches in the passed matrix
-(void) findRandomMatrix:(int)difficulty; //Runs successive buildMatrix methods until a matrix without matches is found for beginning play
-(void) buildMatchMatrix:(int[ARRAYWIDTH][ARRAYHEIGHT])matrixWithMatch; //Sets 1s in matchMatix from matches in the passed matrix
-(void) switchEmptyTiles; //"Drops" filled tiles to blank spaces in the back-end (no animation) 
-(void) switchEmptyTiles:(int[ARRAYWIDTH][ARRAYHEIGHT])_matrix;

//Score methods
//-(NSInteger) calcScore:(NSInteger)numberOfMatches; //Calculates score based on number of matches (soon obsolete)
-(int) calcScoreWithMatrix:(int[SCOREWIDTH][SCOREHEIGHT])_scoreMatrix; //Calculates score based on scoreMatrix values 

//Shake methods
-(void) generateNewTiles;

//Misc
-(void)setDifficultyLevel:(int)diff;
-(int)getDifficultyLevel;

//Movement methods
-(void) shiftUp:(int)x;
-(void) shiftDown:(int)x;
-(void) shiftLeft:(int)y;
-(void) shiftRight:(int)y;

// methods to handle input
-(void) handleTouchFrom: (CGPoint) begin to: (CGPoint) end;
-(void) readyForInput;

/*
 * methods to handle tiles
 */
// create tiles from the given matrix
-(void) loadTiles:(int[ARRAYWIDTH][ARRAYHEIGHT]) _matrix;
// to be called in the VC in order to add the tiles' images to the VC's view
-(void) loadTilesToView: (UIView *) superview;

// check whether tile types on the front-end match types on the back-end
-(BOOL) checkTilesTypeConsistency:(int[ARRAYWIDTH][ARRAYHEIGHT]) expected;
// check whether tile positions on the front-end match positions on the back-end
-(BOOL) checkTilesPositionConsistency;


/* 
 * to accomplish visual motion 
 */
-(void) animateTilesFrom:(int) index withDisplacement:(int) disp onDirection:(direction_t) dir;

-(void) animateTilesFrom:(int) index withOffset:(int) offset onDirection:(direction_t) dir;
-(void) animateTilesFall;
-(void) animateAtomicTilesFall:(NSTimer *) timer;

-(void) updateTilesView;
-(void) updateTilesPosition;
-(void) adjustTilesPosition;

// to accomplish logical motion
-(void) updateTilesFrom:(int) index withDisplacement:(int) disp onDirection:(direction_t) dir;
//-(void) updateTilesFrom:(int) index withOffset:(int) offset onDirection:(direction_t) dir;
-(void) updateTilesFrom:(int[ARRAYWIDTH][ARRAYHEIGHT]) uptodate;

// to determine touch and filter direction
-(direction_t) getDirection:(int) dx :(int) dy;
-(direction_t) filterUsedDirections:(direction_t) raw;
-(BOOL) checkSameAxisForDirection:(direction_t) adir andDirection: (direction_t)  anotherDir;
-(void) resetCurDirection;

// to accomplish matching
-(NSInteger) matchTiles;
-(NSInteger) matchTilesFast;
-(BOOL) checkForEmptyBoard:(int[ARRAYWIDTH][ARRAYHEIGHT]) checkMatrix;
-(BOOL) isEmpty;

// help methods to convert coordinates
-(struct point_t) viewToGridCoord: (CGPoint) coord;
-(CGPoint) gridToViewCoord: (struct point_t) coord;

-(void) loadGameFromFile:(NSString *) filename;
-(BOOL) saveGame;

//Print methods
+(void) printMatrix:(int[ARRAYWIDTH][ARRAYHEIGHT]) _matrix;
// for testing and debugging
-(void) printTilesMatrix;
-(void) printScoreMatrix:(int[9][2]) _matrix;

@end
